﻿using AsmResolver.PE.Builder;
using AsmResolver.PE.File;
using AsmResolver.PE.File.Headers;
using System;
using System.Collections.Generic;
using System.Text;

namespace AsmResolver.PE.Win32Resources.Builder
{
    public class ResourcePEFileBuilder : PEFileBuilderBase<ResourcePEFileBuilder.ResourcePEBuilderContext>
    {
        protected override ResourcePEBuilderContext CreateContext(IPEImage image) => new ResourcePEBuilderContext(image);

        protected override IEnumerable<DataDirectory> CreateDataDirectories(PEFile peFile, IPEImage image, ResourcePEBuilderContext context)
        {
            var resourceDirectory = context.ResourceDirectory;

            return new[]
            {
                new DataDirectory(0, 0),
                new DataDirectory(0, 0),
                new DataDirectory(resourceDirectory.Rva, resourceDirectory.GetPhysicalSize()),
                new DataDirectory(0, 0),
                new DataDirectory(0, 0),
                new DataDirectory(0, 0),
                new DataDirectory(0, 0), // TODO: debug directory
                new DataDirectory(0, 0),
                new DataDirectory(0, 0),
                new DataDirectory(0, 0),
                new DataDirectory(0, 0),
                new DataDirectory(0, 0),
                new DataDirectory(0, 0),
                new DataDirectory(0, 0),
                new DataDirectory(0, 0),
            };
        }
        protected virtual PESection CreateRsrcSection(IPEImage image, ResourcePEBuilderContext context)
        {
            context.ResourceDirectory.AddDirectory(image.Resources);

            return new PESection(".rsrc", SectionFlags.MemoryRead | SectionFlags.ContentInitializedData)
            {
                Contents = context.ResourceDirectory
            };
        }
        protected override IEnumerable<PESection> CreateSections(IPEImage image, ResourcePEBuilderContext context)
        {
            var sections = new List<PESection>();
            if (image.Resources != null && image.Resources.Entries.Count > 0)
                sections.Add(CreateRsrcSection(image, context));

            return sections;
        }

        protected override uint GetEntrypointAddress(PEFile peFile, IPEImage image, ResourcePEBuilderContext context)
         => 0;

        protected override uint GetFileAlignment(PEFile peFile, IPEImage image, ResourcePEBuilderContext context)
         => 0x200;

        protected override uint GetImageBase(PEFile peFile, IPEImage image, ResourcePEBuilderContext context)
        => (uint)image.ImageBase;

        protected override uint GetSectionAlignment(PEFile peFile, IPEImage image, ResourcePEBuilderContext context)
        => 0x2000;

        public class ResourcePEBuilderContext
        {
            /// <summary>
            /// Creates a new managed PE file builder context.
            /// </summary>
            /// <param name="image">The image to build.</param>
            public ResourcePEBuilderContext(IPEImage image)
            {
                ResourceDirectory = new ResourceDirectoryBuffer();
            }

            /// <summary>
            /// Gets the buffer that builds up the win32 resources directory.
            /// </summary>
            public ResourceDirectoryBuffer ResourceDirectory
            {
                get;
            }

        }
    }
}
